using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;

namespace CoastToCoast.Game {
    public class Player {
        private string _name;
        public string Name {
            get { return _name; }
            set { _name = value; }
        }

        private List<Unit> _units = new List<Unit>();
        public IList<Unit> Units {
            get { return new ReadOnlyCollection<Unit>(_units); }
        }

        public void AddUnit(Unit unit) {
            unit.Owner = this;
            _units.Add(unit);
            StartTurn += unit.OnStartTurn;
        }

        public void RemoveUnit(Unit unit) {
            _units.Remove(unit);
            StartTurn -= unit.OnStartTurn;
        }

        private List<City> _cities = new List<City>();
        public IList<City> Cities {
            get { return new ReadOnlyCollection<City>(_cities); }
        }

        public void AddCity(City city) {
            city.Owner = this;
            _cities.Add(city);
            StartProductionPhase += city.OnStartProduction;
            EndProductionPhase += city.OnEndProduction;
        }

        public void RemoveCity(City city) {
            _cities.Remove(city);
            StartProductionPhase -= city.OnStartProduction;
            EndProductionPhase -= city.OnEndProduction;
        }

        private EventHandler _startTurn;
        public event EventHandler StartTurn {
            add {
                _startTurn = (EventHandler)Delegate.Combine(_startTurn, value);
            }
            remove {
                if (_startTurn != null) {
                    _startTurn = (EventHandler)Delegate.Remove(_startTurn, value);
                }
            }
        }

        public void DoStartTurn(EventArgs args) {
            if (_startTurn != null) {
                _startTurn(this, args);
            }
        }

        private EventHandler _endTurn;
        public event EventHandler EndTurn {
            add {
                _endTurn = (EventHandler)Delegate.Combine(_endTurn, value);
            }
            remove {
                if (_endTurn != null) {
                    _endTurn = (EventHandler)Delegate.Remove(_endTurn, value);
                }
            }
        }

        public void DoEndTurn(EventArgs args) {
            if (_endTurn != null) {
                _endTurn(this, args);
            }
        }

        private EventHandler _startProductionPhase;
        public event EventHandler StartProductionPhase {
            add {
                _startProductionPhase = (EventHandler)Delegate.Combine(_startProductionPhase, value);
            }
            remove {
                if (_startProductionPhase != null) {
                    _startProductionPhase = (EventHandler)Delegate.Remove(_startProductionPhase, value);
                }
            }
        }

        public void DoStartProductionPhase(EventArgs args) {
            if (_startProductionPhase != null) {
                _startProductionPhase(this, args);
            }
        }

        private EventHandler _endProductionPhase;
        public event EventHandler EndProductionPhase {
            add {
                _endProductionPhase = (EventHandler)Delegate.Combine(_endProductionPhase, value);
            }
            remove {
                if (_endProductionPhase != null) {
                    _endProductionPhase = (EventHandler)Delegate.Remove(_endProductionPhase, value);
                }
            }
        }

        public void DoEndProductionPhase(EventArgs args) {
            if (_endProductionPhase != null) {
                _endProductionPhase(this, args);
            }
        }

        private EventHandler _startMovementPhase;
        public event EventHandler StartMovementPhase {
            add {
                _startMovementPhase = (EventHandler)Delegate.Combine(_startMovementPhase, value);
            }
            remove {
                if (_startMovementPhase != null) {
                    _startMovementPhase = (EventHandler)Delegate.Remove(_startMovementPhase, value);
                }
            }
        }

        public void DoStartMovementPhase(EventArgs args) {
            if (_startMovementPhase != null) {
                _startMovementPhase(this, args);
            }
        }

        private EventHandler _endMovementPhase;
        public event EventHandler EndMovementPhase {
            add {
                _endMovementPhase = (EventHandler)Delegate.Combine(_endMovementPhase, value);
            }
            remove {
                if (_endMovementPhase != null) {
                    _endMovementPhase = (EventHandler)Delegate.Remove(_endMovementPhase, value);
                }
            }
        }

        public void DoEndMovementPhase(EventArgs args) {
            if (_endMovementPhase != null) {
                _endMovementPhase(this, args);
            }
        }

        public void DoTurn() {
            DoStartTurn(EventArgs.Empty);
            DoStartProductionPhase(EventArgs.Empty);
            DoEndProductionPhase(EventArgs.Empty);
            DoEndMovementPhase(EventArgs.Empty);
            DoStartMovementPhase(EventArgs.Empty);
            DoEndTurn(EventArgs.Empty);
        }
    }
}
